package com.probiz.estore.cart.service.dwr;

import java.math.BigDecimal;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.probiz.estore.Constants;
import com.probiz.estore.cart.service.ShoppingcartManager;
import com.probiz.estore.cart.util.ShoppingCartUtil;
import com.probiz.estore.common.model.cart.Shoppingcart;
import com.probiz.estore.common.model.cart.ShoppingcartItem;
import com.probiz.estore.common.model.product.Product;
import com.probiz.estore.common.model.product.ProductSku;
import com.probiz.estore.common.model.sales.PromoRule;
import com.probiz.estore.common.model.sales.PromoRuleElement;
import com.probiz.estore.common.model.sales.PromoRuleParameter;
import com.probiz.estore.common.service.ProductService;
import com.probiz.estore.common.service.PromoService;
import com.probiz.estore.common.util.NumberUtil;
import com.probiz.estore.core.util.I18nUtil;
import com.probiz.estore.customer.service.FavoriteManager;
import com.probiz.estore.exception.CouponStateException;
import com.probiz.estore.exception.CouponUseException;
import com.probiz.estore.exception.OutOfStockException;
import com.probiz.estore.exception.ProductNoExistException;
import com.probiz.estore.exception.UnderMinimumPurchaseQuantityException;
import com.probiz.estore.product.service.ProductSkuManager;
import com.probiz.estore.sales.service.PromoRuleElementManager;
import com.probiz.estore.sales.service.PromoRuleManager;
import com.probiz.estore.sales.service.PromoRuleParameterManager;
import com.probiz.estore.webapp.util.RequestContext;
public class ShoppingcartDwr {

	private ShoppingcartManager	shoppingcartManager;
	private FavoriteManager		favoriteManager;
	private ProductSkuManager productSkuManager;
	private ProductService productService;
	private PromoRuleManager promoRuleManager;
	private PromoService promoService;
	private PromoRuleElementManager promoRuleElementManager;
	private PromoRuleParameterManager promoRuleParameterManager;
	
	public void setPromoRuleManager(PromoRuleManager promoRuleManager) {
		this.promoRuleManager = promoRuleManager;
	}

	public void setPromoService(PromoService promoService) {
		this.promoService = promoService;
	}

	public void setPromoRuleElementManager(
			PromoRuleElementManager promoRuleElementManager) {
		this.promoRuleElementManager = promoRuleElementManager;
	}

	public void setPromoRuleParameterManager(
			PromoRuleParameterManager promoRuleParameterManager) {
		this.promoRuleParameterManager = promoRuleParameterManager;
	}

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	/**
	 * 添加单一的产品到购物车中
	 * @param request
	 * @param response
	 * @param productCode
	 * @param quantity
	 * @return
	 */
	public String addProductToCart(HttpServletRequest request, HttpServletResponse response,
			String productSkuCode, Integer quantity){	
		return addMultiProductToCart(request, response, productSkuCode, null, quantity);
	}
	
	/**
	 * 添加复合产品到购物车中
	 * @param request
	 * @param response
	 * @param productSkuCode	主产品sku code
	 * @param childSkuCodes		子产品sku code，以英文,隔开
	 * @param quantit			数量
	 * @return
	 */
	public String addMultiProductToCart(HttpServletRequest request, HttpServletResponse response,
			String productSkuCode, String childSkuCodes, Integer quantity){
		
		JSONObject json = new JSONObject();
		
		String[] children = StringUtils.isNotBlank(childSkuCodes)? childSkuCodes.split(","):null;
		Shoppingcart shoppingcart =  ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		try {
			shoppingcartManager.putProductsToCart(shoppingcart, productSkuCode, children, quantity);
			json.put("message", I18nUtil.getInstance().getMessage("shoppingcart.addToCartSuccess"));
			json.put("itemCount", shoppingcart.getShoppingCartItems().size());
			json.put("total", shoppingcart.getTotal().toString());
		} catch (OutOfStockException e) {
			json.put("error", e.getMessage());
			json.put("errorType","outOfStock");
			Product product = productSkuManager.getProductSkuByProductSkuCode(productSkuCode).getProduct();
			json.put("productId",product.getProductId());
			
			//多个配件同时缺货时
			if (children != null && children.length > 0) {
				String errorStr = "";
				for (String sku :children) {
					ProductSku ps = productService.checkInventoryError(sku, 1);
					if (ps != null) {
						errorStr += ps.getProduct().getProductName() + "、";
					}
				}
				if (errorStr != "") {
					errorStr = errorStr.substring(0, errorStr.length() - 1);
					String msg = (I18nUtil.getInstance().getMessage("shoppingcart.message.stockLack.other",new Object[]{errorStr}));
					json.put("errorStr",msg);
					json.put("errorMore","Y");
				}
			}
		} catch (UnderMinimumPurchaseQuantityException e) {
			json.put("error", e.getMessage());	
			json.put("errorType","onderMinimumPurchaseQuantity");
		} catch (ProductNoExistException e) {
			json.put("error", e.getMessage());	
			json.put("errorType","productNoExistException");
		}
		ShoppingCartUtil.getInstance().updateShoppingcartCookie(shoppingcart, response);
		
		return json.toString();
	}
	
	/**
	 * 批量更新购物车中商品的购买数量
	 * @param request
	 * @param response
	 * @param productSkuCode	产品sku code数组
	 * @param sQuantitys		数量数组
	 * @return
	 */
	public String changeQuantitys(HttpServletRequest request, HttpServletResponse response,
			String[] productSkuCodes, String[] sQuantitys){
		JSONObject json = new JSONObject();
		
		if (productSkuCodes != null && productSkuCodes.length > 0 && sQuantitys != null && sQuantitys.length > 0) {
			Integer[] iQuantitys = new Integer[productSkuCodes.length];
			boolean flag = true;
			for (int i = 0; i < productSkuCodes.length; i ++) {
				try {
					iQuantitys[i] = Integer.valueOf(sQuantitys[i]);
				} catch (NumberFormatException e) {
					iQuantitys[i] = 0;
				}
				if (iQuantitys[i]> Constants.MAX_BUY_NUM ) {
					json.put("error", I18nUtil.getInstance().getMessage("shoppingcartItem.quantityScope"));
					json.put("errorType","numberFormat");
					flag = false;
					break;
				}
			}
			Shoppingcart shoppingcart =  ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
			if (flag) {
				try {
					shoppingcartManager.changeQuantitys(shoppingcart, productSkuCodes, iQuantitys);
					ShoppingCartUtil.getInstance().updateShoppingcartCookie(shoppingcart, response);
				} catch (OutOfStockException e) {
					json.put("error", e.getMessage());
					json.put("errorType","outOfStock");
				} catch (UnderMinimumPurchaseQuantityException e) {
					json.put("error", e.getMessage());	
					json.put("errorType","onderMinimumPurchaseQuantity");
				} catch (NumberFormatException e) {
					json.put("error", I18nUtil.getInstance().getMessage("shoppingcartItem.quantityScope"));
					json.put("errorType","numberFormat");
				}
			}
			ShoppingCartUtil.getInstance().updateShoppingcartCookie(shoppingcart, response);
		}
	
		return json.toString();
	}
	
	public String changeQuantity(HttpServletRequest request,HttpServletResponse response, String productSkuCode, String sQuantity){
		JSONObject json = new JSONObject();	
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		try {
			Integer quantity = Integer.valueOf(sQuantity);
			if (quantity > Constants.MAX_BUY_NUM) {
				json.put("error", I18nUtil.getInstance().getMessage("shoppingcartItem.quantityScope"));
				json.put("errorType","numberFormat");
			} else {
				shoppingcartManager.changeQuantity(shoppingcart, productSkuCode, quantity);
				ShoppingcartItem shoppingcartItem = shoppingcart.getShoppingcartItemBySkuCode(productSkuCode);
				json.put("hashCode", shoppingcartItem.hashCode());
				json.put("total", shoppingcartItem.getTotal());
				json.put("itemDiscountAmount", shoppingcartItem.getItemDiscountAmount());
				json.put("totalShow", NumberUtil.format2String(shoppingcartItem.getTotal()));
				json.put("priceShow", NumberUtil.format2String(shoppingcartItem.getDiscountPrice()));
				json.put("itemDiscountAmountShow", NumberUtil.format2String(shoppingcartItem.getItemDiscountAmount()));
			}
		} catch (OutOfStockException e) {
			json.put("error", e.getMessage());
			json.put("errorType","outOfStock");
			Product product = productSkuManager.getProductSkuByProductSkuCode(productSkuCode).getProduct();
			json.put("productId",product.getProductId());
			
			ProductSku ps = productSkuManager.getProductSkuByProductSkuCode(productSkuCode);
			if (ps != null && ps.getInventory() != null) {
				json.put("maxStock",ps.getInventory().getAvailableQuantity());
			}
		} catch (UnderMinimumPurchaseQuantityException e) {
			json.put("error", e.getMessage());	
			json.put("errorType","onderMinimumPurchaseQuantity");
		} catch (NumberFormatException e) {
			json.put("error", I18nUtil.getInstance().getMessage("shoppingcartItem.quantityScope"));
			json.put("errorType","numberFormat");
		}
		ShoppingCartUtil.getInstance().updateShoppingcartCookie(shoppingcart, response);

		json.put("productSkuCode",productSkuCode);
		return json.toString();
	}
	
	public String addFavoriteProduct(HttpServletRequest request, HttpServletResponse response, String productId) {
		JSONObject json = new JSONObject();
		
		if (RequestContext.isAnonymousUser()) {
			json.put("error", I18nUtil.getInstance().getMessage("shoppingcart.notAllowAnonymous"));
		} else {
			boolean nonDuplicate = favoriteManager.addFavoriteProduct(RequestContext.getCurrentUserId(), Integer.valueOf(productId));
			if (nonDuplicate) {
				json.put("message", I18nUtil.getInstance().getMessage("product.addFavorite.success"));
			} else {
				json.put("message", I18nUtil.getInstance().getMessage("product.addFavorite.repeated"));
			}
		}

		return json.toString();
	}
	
	public String deleteFavorite(HttpServletRequest request, HttpServletResponse response, String favoriteId) {
		JSONObject json = new JSONObject();
		
		if (RequestContext.isAnonymousUser()) {
			json.put("error", I18nUtil.getInstance().getMessage("shoppingcart.notAllowAnonymous"));
		} else {
			favoriteManager.deleteFavorite(Integer.valueOf(favoriteId), RequestContext.getCurrentUserId());
		}

		return json.toString();
	}
	

	public void setShoppingcartManager(ShoppingcartManager mgr) {
		this.shoppingcartManager = mgr;
	}

	public ShoppingcartManager getShoppingcartManager() {
		return shoppingcartManager;
	}
		
	public String delProductItem(HttpServletRequest request, HttpServletResponse response, String productSkuCode){
		JSONObject json = new JSONObject();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		shoppingcartManager.delProductItem(shoppingcart, productSkuCode);
		ShoppingCartUtil.getInstance().updateShoppingcartCookie(shoppingcart, response);
		return json.toString();   
	}
	
	public String delGiftCertificateItem(HttpServletRequest request, HttpServletResponse response, String shoppingcartItemGcId){
		JSONObject json = new JSONObject();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		shoppingcartManager.delGiftCertificateItem(shoppingcart, shoppingcartItemGcId);
		return json.toString();
	}
	
	public String clearShoppingcart(HttpServletRequest request, HttpServletResponse response){
		JSONObject json = new JSONObject();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		shoppingcartManager.clearShoppingcart(shoppingcart);
		return json.toString();
	}
	
	//使用优惠券
	public String useCoupon(HttpServletRequest request, HttpServletResponse response, String couponNo){
		JSONObject json = new JSONObject();
		couponNo = couponNo.trim();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		try {
			shoppingcartManager.useCoupon(shoppingcart, couponNo);
		} catch (CouponUseException e) {
			json.put("error", e.getMessage());
		} catch (CouponStateException e) {
			json.put("error", e.getMessage());
		}
		
		return json.toString();
	}
	
	//不使用优惠券
	public String unuseCoupon(HttpServletRequest request, HttpServletResponse response) {
		JSONObject json = new JSONObject();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		shoppingcartManager.unuseCoupon(shoppingcart);
		
		return json.toString();
	}

	//取得购物车商品的种类数量
	public String getShoppingcartItemCount(HttpServletRequest request, HttpServletResponse response) {
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		JSONObject json = new JSONObject();
		json.put("shoppingcartItemCount", shoppingcart.getShoppingCartItems().size());
		return json.toString();
	}
	
	public void setFavoriteManager(FavoriteManager favoriteManager) {
		this.favoriteManager = favoriteManager;
	}

	public void setProductSkuManager(ProductSkuManager productSkuManager) {
		this.productSkuManager = productSkuManager;
	}

	//取得具体的购物车促销提示
	public String getPromoValue(HttpServletRequest request, HttpServletResponse response) {
	
		JSONArray jarray = new JSONArray();
		Shoppingcart shoppingcart = ShoppingCartUtil.getInstance().getCurrentUserShoppingcart();
		List<PromoRule> allCartPromotionRules = promoRuleManager.getAllCartPromotionRulesInProcess();
		
		// 购物车中促销，将促销规则中礼品库存不足的从 allCartPromotionRules 数组中移除！
		List<PromoRule> promoRuleList = promoService.getShoppingcartPromotion(allCartPromotionRules);
		
		// 购物车提示消息
		for (PromoRule entity:promoRuleList) {
			//促销条件
			List<PromoRuleElement> promoRuleElementList = promoRuleElementManager.findAllByRuleId(entity.getPromoRuleId());
			for (PromoRuleElement promoRuleElement : promoRuleElementList) {
				if(promoRuleElement.getType().equals("CartTotalCondition")) {
					Integer elementId= promoRuleElement.getPromoRuleElementId();
					//促销优惠值
					List<PromoRuleParameter> promoRuleParameterList = promoRuleParameterManager.findAllByElementId(elementId);
					for (PromoRuleParameter promoRuleParameter : promoRuleParameterList) {
						if (promoRuleParameter.getParamName().equals("TOTAL_AMOUNT")) {
							BigDecimal paraValue =new BigDecimal(promoRuleParameter.getParamValue());
							BigDecimal cha = paraValue.subtract(shoppingcart.getSubtotal());
							if (cha.compareTo(new BigDecimal(0)) > 0) {
								JSONObject json = new JSONObject();
								json.put("messages1",I18nUtil.getInstance().getMessage("shoppingcart.promos", new Object[]{cha, entity.getPromoRuleName()}) );
								jarray.add(json);
							}
						}
					}
				}
			}
		}
		return jarray.toString();
	}
}